package ir;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Calendar;

public class DataMethodNode extends MemberNode {

  private Method m;
  
  public DataMethodNode(Method m) {
    this.m = m;
  }
  
  /**
   * Generates code for the data class's getter and setter methods;
   * it assumes that the data class will:
   * 
   * for method m(T a),
   * there exists a field 'a' of type 'T'.
   * 
   * if not, well that sucks don't it.
   * @return
   */
  @Override
  public String gen() {
    
    String modifiers = Modifier.toString(m.getModifiers());
    
    if (isQualified()) {
      String params = "";
      
      // TODO GWTIFY THE PARAMS AND RETURNS
      Class<?>[] parameterTypes = m.getParameterTypes();
      for (int i = 0; i < parameterTypes.length; i++) {
        params += gwtifyName(parameterTypes[i]) + " a1";
      }

      FieldNode fieldNode = getFieldNode();

      // Gwtify the Returns, if a getter.
      String returnType = "void";
      if (isGetter())
        returnType = fieldNode.getTypeName();
      
      String generated = modifiers + " "
      + returnType + " "
        + m.getName() + " ("+ params +") ";
  
      //TODO better factoring. Add 'enclose' and 'camelCase' functions.
      
      // chop off the 'set' or 'get'
      String fieldName = m.getName().substring(3,m.getName().length());
      if (isSetter()) {
        String setting = fieldName;
        setting += " = a1;";
        generated += "{" + setting + "}";
      }
      else if (isGetter()) {
        String getting = "return " + 
          fieldName + ";";
        generated += "{" + getting + "}";
      }
      
      return INDENT + generated + "\n";
         
    }
    else return "";
  }
  
  private boolean isSetter() {
    return (m.getName().substring(0,3).equals("set"));
  }
  
  private boolean isGetter() {
    return (m.getName().substring(0,3).equals("get"));
  }

  /**
   * TODO apply filters for axis stuff
   * 
   * @return
   */
  private boolean isQualified() {
    
    // disqualify Axis package.
    Class<?> returnType = m.getReturnType();
    
    if (! returnType.getName().contains("axis"))
    if (m.getName().contains("get") || m.getName().contains("set"))
      return true;
    
    else
        return false;
    else return false;
  }

  public FieldNode getSetFieldNode() {
    if (isSetter()) {
      Class<?>[] parameterTypes = m.getParameterTypes();
      
      Class<?> fieldClass = parameterTypes[0];
      String fieldname = m.getName().substring(3, m.getName().length());
      if (fieldClass.equals(Calendar.class))
        return new CalendarFieldNode(fieldClass, fieldname);
      else
        return new FieldNode(fieldClass, fieldname);
    }
    else
      return null;
  }
  
  public FieldNode getGetFieldNode() {
    if (isGetter()) {
      Class<?> returnType = m.getReturnType();
      
      Class<?> fieldClass = returnType;
      String fieldname = m.getName().substring(3, m.getName().length());
      if (fieldClass.equals(Calendar.class))
        return new CalendarFieldNode(fieldClass, fieldname);
      else
        return new FieldNode(fieldClass, fieldname);
    }
    else
      return null;
  }
  
  public FieldNode getFieldNode() {
    if (getSetFieldNode() == null)
      return getGetFieldNode();
    else return getSetFieldNode();
  }


}
